package com.guojian.common.http;

import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;

import com.google.common.collect.Maps;

/**
 * http请求配置类,简化RestTemplate操作
 * @author guojian
 *
 */

public class HttpConfig {

	private Class<? extends ClientHttpRequestFactory> requestFactory; //httpClient  or restTemplate
	private HttpMethod httpMethod;
	private HttpHeaders httpHeaders;
	private Object requestBody;
	private String url;

	public static HttpConfig defaultConfig() {
		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.add(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36");
		httpHeaders.add(HttpHeaders.CONNECTION, "keep-alive");
		httpHeaders.add(HttpHeaders.CACHE_CONTROL, "no-cache");
		return new HttpConfig(HttpComponentsClientHttpRequestFactory.class, httpHeaders);
	}

	public HttpConfig(Class<? extends ClientHttpRequestFactory> requestFactory, HttpHeaders httpHeaders) {
		super();
		this.requestFactory = requestFactory;
		this.httpHeaders = httpHeaders;
	}

	public Class<? extends ClientHttpRequestFactory> getRequestFactory() {
		return requestFactory;
	}

	public void setRequestFactory(Class<? extends ClientHttpRequestFactory> requestFactory) {
		this.requestFactory = requestFactory;
	}

	public HttpMethod getHttpMethod() {
		return httpMethod;
	}

	public void setHttpMethod(HttpMethod httpMethod) {
		this.httpMethod = httpMethod;
	}

	public HttpHeaders getHttpHeaders() {
		return httpHeaders;
	}

	public HttpConfig setHttpHeaders(HttpHeaders httpHeaders) {
		this.httpHeaders = httpHeaders;
		return this;
	}

	public HttpConfig addHttpHeader(String headerName, @Nullable String headerValue) {
		getHttpHeaders().remove(headerName);
		getHttpHeaders().add(headerName, headerValue);
		return this;
	}

	public Object getRequestBody() {
		return requestBody;
	}

	public HttpConfig setRequestBody(Object requestBody) {
		this.requestBody = requestBody;
		return this;
	}

	public String getUrl() {
		return url;
	}

	public HttpConfig setUrl(String url) {
		this.url = url;
		return this;
	}

	public HttpConfig get() {
		setHttpMethod(HttpMethod.GET);
		return this;
	}

	public HttpConfig get(String url) {
		setHttpMethod(HttpMethod.GET);
		setUrl(url);
		return this;
	}

	public HttpConfig post() {
		setHttpMethod(HttpMethod.POST);
		return this;
	}

	public HttpConfig post(String url) {
		setHttpMethod(HttpMethod.POST);
		setUrl(url);
		return this;
	}

	@SuppressWarnings("unchecked")
	public HttpConfig addJsonParams(String name, Object value) {
		if (getRequestBody() == null) {
			this.requestBody = Maps.newLinkedHashMap();
		}
		Map<String, Object> params = (Map<String, Object>) this.requestBody;
		params.put(name, value);
		return this;
	}

	@SuppressWarnings("unchecked")
	public HttpConfig addJsonParams(Map<String, Object> params) {
		if (getRequestBody() == null) {
			this.requestBody = params;
		} else {
			Map<String, Object> oldParams = (Map<String, Object>) this.requestBody;
			oldParams.putAll(params);
		}
		return this;
	}

	/**
	 * 
	 * private boolean isMultipart(MultiValueMap<String, ?> map, @Nullable MediaType contentType) {
		if (contentType != null) {
			return contentType.getType().equalsIgnoreCase("multipart");
		}
		for (List<?> values : map.values()) {
			for (Object value : values) {
				if (value != null && !(value instanceof String)) {
					return true;
				}
			}
		}
		return false;
	}
	 * @param name
	 * @param value 如果没有设置content-type ,并且value不是string类型,会被当成文件
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public HttpConfig addFormParams(String name, Object value) {
		if (getRequestBody() == null) {
			this.requestBody = new LinkedMultiValueMap<>();
		}
		LinkedMultiValueMap<String, Object> params = (LinkedMultiValueMap<String, Object>) this.requestBody;
		params.add(name, value);
		return this;
	}

	@SuppressWarnings("unchecked")
	public HttpConfig addFormParams(LinkedMultiValueMap<String, Object> formParams) {
		if (getRequestBody() == null) {
			this.requestBody = formParams;
		}else{
			LinkedMultiValueMap<String, Object> params = (LinkedMultiValueMap<String, Object>) this.requestBody;
			params.addAll(formParams);
		}
		return this;
	}

}
